/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.p2psimulator.entity.overlaynetwork;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import org.p2psimulator.engine.Environment;
import org.p2psimulator.entity.Id;
import org.p2psimulator.entity.OverlayNetwork;
import org.p2psimulator.entity.overlaynetwork.routingtable.FloodRoutingTable;

/**
 *
 * @author aamorim
 */
public abstract class FloodOverlay extends OverlayNetwork {

    // TODO ADIONAR REPUTATION REPOSITORY AO OVERLAY NETWORK
    protected Map<Id, FloodRoutingTable> overlayMap;
    
    public FloodOverlay(Environment env) {
        super(env);
        this.overlayMap  = new HashMap<Id, FloodRoutingTable>();
    }

    public abstract FloodRoutingTable getPeerNeighbors(Id id);

    public abstract List<Id> getUncompletePeerList(int maxNeighbors, Id except);
    public abstract List<Id> getOnlineUncompletePeerList(int maxNeighbors, Id except);
    public abstract void associatePeers(Id a, Id b);

    public void connectPeers(Id id, int maxNeighbors) {

        Random r = new Random();
        synchronized (overlayMap) {
            FloodRoutingTable tableA = (FloodRoutingTable)overlayMap.get(id);

            List<Id> vector = getUncompletePeerList(maxNeighbors, id);

            if (vector.size() != 0) {
                for (int i = 2 * vector.size(); i >= 0; i--) {
                    int k = r.nextInt(vector.size());
                    Id n = vector.get(k);
                    FloodRoutingTable tableB = (FloodRoutingTable)overlayMap.get(n);
                    if (tableA.size() < maxNeighbors) {
                        tableA.insertNeighbor(n);
                        tableB.insertNeighbor(id);
                    } else {
                        break;
                    }
                }
            } else {
                return;
            }
        }
    }
}
